/**
  ******************************************************************************
  * @file    Project/main.c 
  * @author  MCD Application Team
  * @version V2.2.0
  * @date    30-September-2014
  * @brief   Main program body
   ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
  *
  * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
  * You may not use this file except in compliance with the License.
  * You may obtain a copy of the License at:
  *
  *        http://www.st.com/software_license_agreement_liberty_v2
  *
  * Unless required by applicable law or agreed to in writing, software 
  * distributed under the License is distributed on an "AS IS" BASIS, 
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
  ******************************************************************************
  */ 

/* Includes ------------------------------------------------------------------*/
#ifdef __HOST_MICOM_SYSTEM__
#include "gpio.h"
#include "config.h"
#endif

#include "typedef.h"
#include "pr2000.h"
#include "pr2000_table.h"
#include "pr2000_func.h"
#include "pr2000_ceqfunc.h"
#include "pr2000_user_config.h"
#include "pr2000_main.h"

#ifdef __HOST_LINUX_SYSTEM__
#include <linux/string.h>
#endif


uint8_t gFlagIrqExtiPR2000 = 0;
uint8_t gFlagTimer100MsecPR2000 = 0;


char gbNovideStatus[MAX_PR2000_CHIPCNT] = {1, }; //1:novideo
char gbvideoStable[MAX_PR2000_CHIPCNT]= {0, };

_stPrRxMode gstPrRxMode[MAX_PR2000_CHIPCNT];
_stPrRxMode gstPrRxMode_backup[MAX_PR2000_CHIPCNT];

uint8_t gInterfaceChip = 0; //0:parallel chip(0x5C)
uint8_t gDebugCtrlPr2000 = 1; //0:don't control PR2000

// ----------------------------------------------------------------------
// Static Global Data section variables
// ----------------------------------------------------------------------
#define PR2000_SLV_ADDR         (0x5C<<1)
_drvHost gstDrvHost[MAX_PR2000_CHIPCNT];

const char *strPlatfromTitle = "!!! PR2000 Evaluation Platform PSL";
#define verMajor(x)	((x>>8)&0xFF)
#define verMinor(x)	((x)&0xFF)
const uint16_t numVerPlatform = 0x0208 ; //(major | minor)
//keep format  ^^^^^^^^^^^^^^^^^^^^^^^^ --> used for parsing version by scripts

typedef struct
{
	unsigned short preg; //page+reg;
	unsigned char Mbit;
	unsigned char Lbit;
}_stTestRegBit;


/* Private variables ---------------------------------------------------------*/


#define sFLASH_SECTOR_SIZE	(0x1000)
#define sFLASH_BUFFER_SIZE	(0x10)


////////////////////////////////////////////////////////////////////////////////////////////////////
/**
 * @brief  Main loop
 * @param  None
 * @retval None
 */
uint8_t findPr2000SlvAddr[MAX_PR2000_CHIPCNT] = {0, };
uint16_t findPr2000ChipID[MAX_PR2000_CHIPCNT] = {0, };
uint8_t findPr2000RevID[MAX_PR2000_CHIPCNT] = {0, };
int i2cRW_Verify[MAX_PR2000_CHIPCNT] = {0, };
int findPr2000SlvAddrInx = 0;
uint8_t flagOSDTimeOutCnt = 0;
void pr2000_io_init(void)
{
#ifdef __HOST_MICOM_SYSTEM__

    GPIO GPA4 = {INPUT,ON,OFF,HIGH,4,GPIOA};
    GPIO GPA5 = {OUTPUT,OFF,OFF,HIGH,5,GPIOA};
	GPIO GPA6 = {OUTPUT,OFF,OFF,HIGH,6,GPIOA};
	GPIO GPA7 = {OUTPUT,OFF,OFF,HIGH,7,GPIOA};

    GPIO GPC4 = {INPUT,OFF,OFF,LOW,4,GPIOC}; // back
	GPIO GPC5 = {INPUT,OFF,OFF,LOW,5,GPIOC}; //right
    
    setgpio(GPA4, 4);
    setgpio(GPA5, 5);
    setgpio(GPA6, 6);
	setgpio(GPA7, 7);

    setgpio(GPC4, 4);
    setgpio(GPC5, 5);
    
    /* pr2000 reset*/
	GPA5.gpio_out_val = LOW;
	setgpio(GPA5, 5);
	twdDelay(10);
	GPA5.gpio_out_val = HIGH;
	setgpio(GPA5, 5);
    twdDelay(10);
#endif   
}

void pr2000_init(void)
{
    
	int i = 0;
	int chipInx;

   
    
	/* Initialize variable */
	for(i = 0; i < MAX_PR2000_CHIPCNT; i++)
	{
		gbNovideStatus[i] = 1; //1:novideo
        gbvideoStable[i] = 0;
		gstPrRxMode[i].standard = (enum _eCameraStandard)DEFAULT_CAMERA_STANDARD;
		gstPrRxMode[i].cameraResolution = (enum _eCameraResolution)DEFAULT_CAMERA_RESOLUTION;
		gstPrRxMode[i].vidOutResolution = (enum _eVideoResolution)stDefaultCameraVideoRelation[DEFAULT_CAMERA_RESOLUTION].eVideoResolution;
	}

	/* Set PR2000 Chip */
	if(gDebugCtrlPr2000) //0:don't control PR2000
	{    
		if( (gFindPr2000SlvAddrCnt = PR2000_CheckChipID_SWReset(0, MAX_PR2000_CHIPCNT, findPr2000SlvAddr, findPr2000ChipID, findPr2000RevID, i2cRW_Verify)) > 0) 
		{    
			for(chipInx = 0, findPr2000SlvAddrInx = 0; chipInx < MAX_PR2000_CHIPCNT; chipInx++)
			{
				if( (findPr2000SlvAddrInx < gFindPr2000SlvAddrCnt) && (findPr2000SlvAddr[chipInx] != 0) )
				{    
					if( (gpDrvHost[findPr2000SlvAddrInx] = (_drvHost *)&gDrvHost[findPr2000SlvAddrInx]) == NULL)
					{
						AppErrorString("ERROR: Can't allocate memory\n");
					}
					memset(gpDrvHost[findPr2000SlvAddrInx], 0, sizeof(_drvHost));
					gpDrvHost[findPr2000SlvAddrInx]->i2cSlvAddr = findPr2000SlvAddr[findPr2000SlvAddrInx];
					gpDrvHost[findPr2000SlvAddrInx]->chipID = findPr2000ChipID[findPr2000SlvAddrInx];
					gpDrvHost[findPr2000SlvAddrInx]->u8RevID = findPr2000RevID[findPr2000SlvAddrInx];
					gpDrvHost[findPr2000SlvAddrInx]->i2cRW_Verify = i2cRW_Verify[findPr2000SlvAddrInx];
					//gpDrvHost[findPr2000SlvAddrInx]->wqPoll = 0;
					init_waitqueue_head(&gpDrvHost[findPr2000SlvAddrInx]->wqPoll);
					gpDrvHost[findPr2000SlvAddrInx]->minor = -1;


					memcpy(&gpDrvHost[findPr2000SlvAddrInx]->stPrRxMode, &gstPrRxMode[findPr2000SlvAddrInx], sizeof(_stPrRxMode));
					if(PR2000_Initialize(0, findPr2000SlvAddr[findPr2000SlvAddrInx]) < 0) 
					{
						AppError("PR2000 initialize(slv:0x%02x)\n", findPr2000SlvAddr[findPr2000SlvAddrInx]);
					}

					findPr2000SlvAddrInx++;
				}
			}
		}
    }
	else
	{
		gFindPr2000SlvAddrCnt = 0; 
	}

	AppPrint("Find PR2000 cnt:%bd\n", gFindPr2000SlvAddrCnt);
}


void pr2000_loop(void)
{
	/* Infinite loop */  
    int chipInx;

		//if(gFlagIrqExtiPR2000 == 1)
		//{
		//	gFlagIrqExtiPR2000 = 0;
			//AppPrintString("FlagIrqExti\n");
		//}
		//if(gFlagTimer100MsecPR2000 == 1)
		{
		//	gFlagTimer100MsecPR2000 = 0;
			//AppPrintString("FlagTimer100Msec TEST\n");


			for(chipInx = 0; chipInx < MAX_PR2000_CHIPCNT; chipInx++)
			{/*{{{*/
				if(findPr2000SlvAddr[chipInx] == 0)
				{    
					continue;
				}

				if( PR2000_Isr(0, PR2000_ATTR_CHIP[chipInx].i2cSlvAddr, (void *)gpDrvHost[chipInx]) < 0)
				{
					AppErrorString("Invalid Isr\n");
				}
				if( (_TEST_BIT(IRQ_NOVID, &gpDrvHost[chipInx]->stPR2000_Isr.stUserPoll.bitIrq)) )
				{
					_CLEAR_BIT(IRQ_NOVID, &gpDrvHost[chipInx]->stPR2000_Isr.stUserPoll.bitIrq);
					if(_TEST_BIT(IRQ_NOVID, &gpDrvHost[chipInx]->stPR2000_Isr.stUserPoll.bitIrqStatus))
					{
						AppPrint("-->%bd-Novideo\n", chipInx);
						gbNovideStatus[chipInx] = 1; //novideo
						gbvideoStable[chipInx] = 0;
					}
					else
					{
						AppPrint("-->%bd-Video\n", chipInx);
						gbNovideStatus[chipInx] = 0; //video
						
					}
				}

				if( (_TEST_BIT(IRQ_SET_RXMODE, &gpDrvHost[chipInx]->stPR2000_Isr.stUserPoll.bitIrq)) )
				{
				//	enum _eCameraStandard cameraStandard;
					//enum _eCameraResolution cameraResolution;
				//	enum _eVideoResolution videoResolution;
					int reJudge = 0;

					_CLEAR_BIT(IRQ_SET_RXMODE, &gpDrvHost[chipInx]->stPR2000_Isr.stUserPoll.bitIrq);

					memcpy( &gstPrRxMode[chipInx], &gpDrvHost[chipInx]->stPrRxMode, sizeof(_stPrRxMode));
                    gbvideoStable[chipInx] = 1;
					AppPrint("### %d-Rxmode => Camera:%bx(%s), cameraResolution:%bx(%s), videoResolution:%bx(%s)\n", chipInx COMMA gstPrRxMode[chipInx].standard COMMA _strCameraStandard[gstPrRxMode[chipInx].standard] COMMA gstPrRxMode[chipInx].cameraResolution COMMA _strCameraResolution[gstPrRxMode[chipInx].cameraResolution] COMMA gstPrRxMode[chipInx].vidOutResolution COMMA _strVideoResolution[gstPrRxMode[chipInx].vidOutResolution]);
#if 0 //Already driver setting. If you want, uncomment.
					PR2000_SetTableStdResol(0, PR2000_ATTR_CHIP[chipInx].i2cSlvAddr, gstPrRxMode[chipInx].standard, gstPrRxMode[chipInx].vidOutResolution);
#ifdef SUPPORT_UTC
					PR2000_UTC_SetTable(0, PR2000_ATTR_CHIP[chipInx].i2cSlvAddr, gstPrRxMode[chipInx].standard, gstPrRxMode[chipInx].cameraResolution);
#endif // SUPPORT_UTC
#ifdef SUPPORT_OSG
					PR2000_OSG_SetTable(0, PR2000_ATTR_CHIP[chipInx].i2cSlvAddr, gstPrRxMode[chipInx].standard, gstPrRxMode[chipInx].vidOutResolution);
#endif // SUPPORT_OSG
#ifdef SUPPORT_FPGA
					PR2000_FPGA_SetTable(0, PR2000_ATTR_CHIP[chipInx].i2cSlvAddr);
#endif // SUPPORT_FPGA
#endif
				}

				if( (_TEST_BIT(IRQ_UTC, &gpDrvHost[chipInx]->stPR2000_Isr.stUserPoll.bitIrq)) )
				{
					_CLEAR_BIT(IRQ_UTC, &gpDrvHost[chipInx]->stPR2000_Isr.stUserPoll.bitIrq);
					if( (_TEST_BIT(IRQ_UTC_TX, &gpDrvHost[chipInx]->stPR2000_Isr.stUserPoll.bitIrq)) )
					{
						_CLEAR_BIT(IRQ_UTC_TX, &gpDrvHost[chipInx]->stPR2000_Isr.stUserPoll.bitIrq);
						AppPrintString("UTC TX\n");
					}
					if( (_TEST_BIT(IRQ_UTC_RX, &gpDrvHost[chipInx]->stPR2000_Isr.stUserPoll.bitIrq)) )
					{
						_CLEAR_BIT(IRQ_UTC_RX, &gpDrvHost[chipInx]->stPR2000_Isr.stUserPoll.bitIrq);
						AppPrintString("UTC RX\n");
					}
				}
			}/*}}}*/

		}


}

void pr2000_Input_chg(unsigned char chn)
{
    
    if(chn == 0)
    {
        PR2000_ATTR_CHIP[0].vinMode = 1; //VinP pin
        PR2000_PageWriteMaskBit(0,0xb8,0,0x14,3,1);
    }
    else if(chn == 1)
    {
         PR2000_ATTR_CHIP[0].vinMode = 3;//VinN pin
         PR2000_PageWriteMaskBit(0,0xb8,0,0x14,3,3);
    }
}


#ifdef USE_FULL_ASSERT

/**
 * @brief  Reports the name of the source file and the source line number
  *   where the assert_param error has occurred.
  * @param file: pointer to the source file name
  * @param line: assert_param error line source number
  * @retval : None
  */
void assert_failed(u8* file, u32 line)
{ 
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %bd\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif


/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
